package com.zqweb.gulimall.essearch.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static java.util.concurrent.CompletableFuture.runAsync;

public class ThreadTest2 {
    public static ExecutorService threadPool = Executors.newFixedThreadPool(15);

    public static void main(String[] args) {
        System.out.println("main方法开始执行...");
        // 创建异步对象，启动异步任务
        // void无返回值类型：传入Runnable接口实现类、线程池对象
        /*CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(() -> {
            String name = Thread.currentThread().getName();
            long id = Thread.currentThread().getId();
            System.out.println("name = " + name + ",id = " + id + "的分线程开始执行业务任务了...");
        },threadPool);*/
        // 有返回值类型：传入Supplier接口实现类、线程池对象
        /*CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {
            String name = Thread.currentThread().getName();
            long id = Thread.currentThread().getId();
            System.out.println("name = " + name + ",id = " + id + "的分线程开始执行业务任务了...");
            int res = 10 / 0;
            return res;
        },threadPool).whenComplete((trueRes,expRes) -> {
            // 业务任务执行完毕后的执行回调（成功或失败）参数1：成功响应结果  参数2：失败响应结果
            System.out.printf("业务任务执行完毕，成功响应结果为：%s，失败响应结果为：%s\n",trueRes,expRes);
        }).exceptionally(throwable -> {
            System.out.printf("业务任务执行失败，原因为：%s\n",throwable.getMessage());
            return 10;// 业务任务执行失败后，返回的默认值
        });
        Integer res = null;
        try {
            res = completableFuture2.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }*/
        /*CompletableFuture<Integer> completableFuture3 = CompletableFuture.supplyAsync(() -> {// 供给型函数式接口，无输入参数，有1个输出参数
            int res = 10 / 0;
            return res;
        },threadPool).handle((trueRes,expRes) -> {
            // 业务任务执行完毕（成功或失败）后的最终结果处理 参数1：成功处理结果  参数2：失败处理结果
            if(trueRes != null){// 成功处理，则expRes = null
                System.out.println("业务任务执行成功，结果为：" + trueRes);
                return trueRes;
            }else if(expRes != null){// 失败处理，则trueRes = null
                System.out.println("业务任务执行失败，原因为：" + expRes);
                return 0;
            }else{
                return 0;
            }
        });*/
        /*
            线程串行化：
                1）thenRunAsync()：接收1个Runnable接口，不适用有返回值类型的异步任务对象，
                因为该方法不能接收上一个异步任务的成功执行结果，而且该方法本身也没有返回结果
                2）thenAccept()：接收1个Consumer接口，可以接收上一个异步任务成功执行后的结果，
                但是该方法本身并没有返回结果
                3）thenApply()：接收1个BiFunction接口，可接收上一个异步任务成功执行后的结果，
                该方法本身也有返回结果
         */
        /*CompletableFuture<Void> completableFuture4 = CompletableFuture.supplyAsync(() -> {// 供给型函数式接口，无输入参数，有1个输出参数
            System.out.println("正在执行第1个异步任务...");
            int res = 10 / 0;
            return res;
        },threadPool).thenRunAsync(() -> {
            System.out.println("上一个异步任务执行成功后，立即启用下1个任务...");
        },threadPool);*/
        /*CompletableFuture<Void> completableFuture4 = CompletableFuture.supplyAsync(() -> {// 供给型函数式接口，无输入参数，有1个输出参数
            System.out.println("正在执行第1个异步任务...");
            int res = 10 / 2;
            return res;
        },threadPool).thenAcceptAsync(res -> {
            System.out.printf("上一个异步任务执行成功，结果为：%s,然后立即启用下1个任务...\n",res);
        },threadPool);*/
        CompletableFuture<Integer> completableFuture4 = CompletableFuture.supplyAsync(() -> {// 供给型函数式接口，无输入参数，有1个输出参数
            System.out.println("正在执行第1个异步任务...");
            int res = 10 / 2;
            return res;
        },threadPool).thenApplyAsync(res -> {
            System.out.printf("上一个异步任务执行成功，结果为：%s,然后立即启用下1个任务...\n",res);
            return res + 5;
        },threadPool);

        Integer res = null;
        try {
            res = completableFuture4.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.printf("异步编排业务任务执行结果为：%s\n",res);
        threadPool.shutdown();// 释放本次线程的资源调用
        System.out.println("main方法执行结束...");
    }

}
